package org.struts.mvc.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.struts.mvc.StrutsConfig;
import org.struts.mvc.action.form.ActionForm;

public class StrutsRequestUtil {
	
	private static Logger logger = Logger.getLogger(StrutsRequestUtil.class);
	
	public static Map<String,StrutsConfig> STRUTS_CONFIG_MAPPING = new HashMap<String,StrutsConfig>();
	
	private final static String DEFAULT_BEAN_CLASS = "org.struts.mvc.action.form.ActionForm";
	
	/**
	 * 根据类名称获取对象
	 * @param className
	 * @return
	 */
	public static Object getClassByName(final String className){
		Class<?> clzz = null;
		try {
			clzz = Class.forName(className);
			return clzz.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return clzz;
		
	}
	/**
	 * 通过反射设置填充属性值
	 * @param className
	 * @return
	 */
	public static ActionForm fullForm(final String className,HttpServletRequest request){
		ActionForm form  = null;
		try {
			//获取对象类
			Class<?> clazz = Class.forName(className);
			if(!className.equals(DEFAULT_BEAN_CLASS)){
				form = (ActionForm) clazz.newInstance();
				Field [] fields = clazz.getDeclaredFields();
				for (Field field : fields) {
					field.setAccessible(true); //设置private 可以访问
					field.set(form, request.getParameter(field.getName())); //设置属性值
					field.setAccessible(false);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return form;
	}
	
	/**
	 * 初如化解析XML
	 * @param configPath
	 * @throws JDOMException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public static void initStrutsConfig(String configPath) throws JDOMException, IOException{
//		InputStream is = StrutsRequestUtil.class.getClassLoader().getResourceAsStream("struts-congfig.xml");
		SAXBuilder xmlBuilder = new SAXBuilder();
		Document doc = xmlBuilder.build(new File(configPath));
		Element rootElement = doc.getRootElement();
		Element actionMappingElement = rootElement.getChild("action-mapping");
		List<Element> actionMappings = actionMappingElement.getChildren("action");
		StrutsConfig strutsConfig = null;
		for (Element actionMapping : actionMappings) {
			strutsConfig = new StrutsConfig();
			String actionName = actionMapping.getAttributeValue("name");
			strutsConfig.setActionName(actionName);
			String actionClass = actionMapping.getAttributeValue("class");
			strutsConfig.setActionClass(actionClass);
			String actionPath = actionMapping.getAttributeValue("path");
			strutsConfig.setActionPath(actionPath);
			
			List<Element> forwardElements = actionMapping.getChildren("forward");
			Map<String,String> forwardMap = new HashMap<String, String>();
			for (Element forwardElement : forwardElements) {
				String forwardName = forwardElement.getAttributeValue("name");
				String value = forwardElement.getAttributeValue("value");
				forwardMap.put(forwardName, value);
			}
			strutsConfig.setForwardMap(forwardMap);
			
			Element formBeanElement = rootElement.getChild("formbeans");
			List<Element> beanList = formBeanElement.getChildren();
			for (Element bean : beanList) {
				String beanName = bean.getAttributeValue("name");
				if(StringUtils.equals(beanName, actionName)){
					String beanClass = bean.getAttributeValue("class");
					strutsConfig.setBeanName(beanName);
					strutsConfig.setBeanClass(beanClass);
					break;
				}else{
					strutsConfig.setBeanName("");
					strutsConfig.setBeanClass(DEFAULT_BEAN_CLASS);
				}
			}
			
			//注册数据到MAP
			StrutsRequestUtil.registStrutsConfigMapping(actionPath, strutsConfig);
		}
	}
	
	/**
	 * 注册数据
	 * @param key
	 * @param strutsConfig
	 */
	public static void registStrutsConfigMapping(String key,StrutsConfig strutsConfig){
		StrutsRequestUtil.STRUTS_CONFIG_MAPPING.put(key, strutsConfig);
	}
	
	/**
	 * 获取Config数据
	 * @param key
	 * @return
	 */
	public static StrutsConfig getStrutsConfig(final String key){
		return StrutsRequestUtil.STRUTS_CONFIG_MAPPING.get(key);
	}
	
	
	public static void main(String[] args) {
		try {
			String filePath = StrutsRequestUtil.class.getClassLoader().getResource("").getFile();
			StrutsRequestUtil.initStrutsConfig(filePath + "struts-congfig.xml");
			Map<String,StrutsConfig> map = StrutsRequestUtil.STRUTS_CONFIG_MAPPING;
			Set<Entry<String, StrutsConfig>> strutsSet = map.entrySet();
			for (Entry<String, StrutsConfig> entry : strutsSet) {
				System.out.println(entry);
			}
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
